package com.zeratul.common.core.result;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.zeratul.common.core.result.codes.ResultCodes;
import com.zeratul.common.core.result.page.BaseResult;
import com.zeratul.common.core.utils.I18nUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * 统一返回对应
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class R<T> extends BaseResult<T> implements Serializable {

    /**
     * 响应码
     */
    private Integer code;

    /**
     * 响应信息
     */
    private String msg;

    /**
     * 响应数据
     */
    private T data;

    /**
     * 全局追踪号
     */
    private String traceId;

    /**
     * msg属性的get方法
     */
    public String getMsg() {
        return I18nUtils.getMessage(String.valueOf(this.code), msg);
    }

    /**
     * 判断是否成功
     */
    @JsonIgnore
    public boolean isSuccess() {
        return ResultCodes.SUCCESS.getCode().equals(this.code);
    }

    /**
     * 判断是否失败
     */
    @JsonIgnore
    public boolean isFail() {
        return !isSuccess();
    }

    /**
     * 生成成功的对象
     */
    public static <T> R<T> success() {
        return success(null);
    }

    /**
     * 生成成功的带数据的对象
     */
    public static <T> R<T> success(T data) {
        return new R<>(ResultCodes.SUCCESS.getCode(), ResultCodes.SUCCESS.getMessage(), data, null);
    }

    /**
     * 默认失败的R对象
     */
    public static <T> R<T> fail() {
        return fail(ResultCodes.FAIL);
    }

    /**
     * 根据传入的code和msg，生成失败的R对象
     */
    public static <T> R<T> fail(Integer code, String msg) {
        return fail(code, msg, null);
    }

    /**
     * 根据传入的code、msg和data，生成失败的R对象
     */
    public static <T> R<T> fail(Integer code, String msg, T data) {
        return new R<>(code, msg, data, null);
    }

    /**
     * 根据传入的ResultCodes对象，生成失败的R对象
     */
    public static <T> R<T> fail(ResultCodes resultCodes) {
        return fail(resultCodes, null);
    }

    /**
     * 根据传入的ResultCodes和data，生成失败的R对象
     */
    public static <T> R<T> fail(ResultCodes resultCodes, T data) {
        return new R<>(resultCodes.getCode(), resultCodes.getMessage(), data, null);
    }
}
